package ro.fwd{
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.display.Bitmap;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.IOErrorEvent;
	import gs.TweenMax;
	import gs.easing.Expo;
	import ro.fwd.utils.DSRWithoutLimit;
	import ro.fwd.transitions.Pixelator;

	public class ImageScreen extends Sprite {
		/*
		THIS CLASS IS LOADING AND CREATING THE LOADED IMAGE
		*/
		public static const LOADING_START:String = "LOADING_START";
		public static const LOADING_DONE:String = "LOADING_DONE";
		public static const LOADING_PROGRESS:String = "LOADING_PROGRESS";
		
		private var _holder:Sprite;//the main Sprite holder
		private var _curHolder:Sprite;//holds a reference to the current Sprite holder
		private var _curImage:Sprite;//holds a reference to the current Sprite that is holding the image
		private var _curMask:Sprite;//holds a reference to the current Sprite mask
		private var W:Number;//the width of the image
		private var H:Number;//the height of the image
		public var percent:Number;//the percent set when the image is loading
		private var px:Pixelator;

		//constructor
		public function ImageScreen() {
			 px = new Pixelator();
			addChild(px);
			_holder =  new Sprite();
			addChild(_holder);
			addEventListener(Event.ADDED_TO_STAGE,thisAddedToStage);
		}
		
		//when this is added to stage we can resize the Sprites
		private function thisAddedToStage(e:Event):void{
			stage.addEventListener(Event.RESIZE, resizeImage);
		}
		
		//this function creates all the Sprites and stats loading the current an image
		public function createImage(path:String):void {
			var imageAndMaskHolder:Sprite =  new Sprite();
			var imgSprite:Sprite =  new Sprite();
			var msk:Sprite = new Sprite();
			msk.graphics.beginFill(0x00FF00);
			msk.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
			msk.graphics.endFill();
			_holder.addChild(imageAndMaskHolder);
			imageAndMaskHolder.addChild(imgSprite);
			imageAndMaskHolder.addChild(msk);
			imgSprite.mask = msk;
			loadImage(path,imageAndMaskHolder,imgSprite,msk);
		}
		
		//resize the _curImage Sprite
		private function resizeImage(e:Event):void{
			try{
				DSRWithoutLimit.resize(_curImage,W,H,stage.stageWidth,stage.stageHeight);
				resizeCurrentMask();
			}catch(e:Error){
				
			}
			trace("RESIZING");
		}
		
		//resize the _curMask Sprite
		private function resizeCurrentMask():void{
			_curMask.width = stage.stageWidth;
			_curMask.height =  stage.stageHeight;
		}

		//this function is holding the logic for loading and adding the big image and the small image (the one in the right part of the stage)
		private function loadImage(_path:String,imageAndMaskHolder:Sprite,holder:Sprite, msk:Sprite):void { 
			disable();
			dispatchEvent(new Event("LOADING_START"));
			var _loader:Loader = new Loader();
			_loader.load(new URLRequest(_path));
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,handleComplete);
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,handleProgress);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,handleIoError);
			function handleProgress(e:ProgressEvent):void {
				percent = e.bytesLoaded/e.bytesTotal;
				dispatchEvent(new Event("LOADING_PROGRESS"));

			}
			function handleIoError(e:IOErrorEvent):void {
				//enableAll();
			}
			function handleComplete(e:Event) {
				stopToPanImage();
				var _bitmap:Bitmap = new Bitmap();
				_bitmap= Bitmap(_loader.content);
				_bitmap.smoothing=true;
				holder.addChild(_bitmap);
				//creating adn adding a bitmap to the  _holder_small Sptite
				_curHolder = imageAndMaskHolder;
				_curHolder.x =  stage.stageWidth;
				W=_bitmap.width;//setting the W
				H=_bitmap.height;//setting the H
				_curImage = holder;
				_curMask = msk;
				DSRWithoutLimit.resize(_curImage,W,H,stage.stageWidth,stage.stageHeight);
				resizeCurrentMask();
				_curHolder.x = 0;
				//starting the pixel transition
				px.startTransition(_bitmap, Pixelator.PIXELATION_MEDIUM);
				px.addEventListener(Pixelator.PIXEL_TRANSITION_COMPLETE, cleanHolder);
				setChildIndex(px,numChildren -1);
				//TweenMax.to(_curHolder,.8,{x:0,ease:Expo.easeOut,onComplete:cleanHolder});
				dispatchEvent(new Event("LOADING_DONE"));
				_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,handleIoError);
				_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,handleProgress);
				_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,handleComplete);
				_loader=null;
			}
		}
		
		
		
		//this function removes and dispose the bitmapData if the _holder Sprite has more then one child
		private function cleanHolder(e:Event = null):void{
			while(_holder.numChildren > 1){
				//var sprite:Sprite = 
				Bitmap(Sprite(Sprite(_holder.getChildAt(0)).getChildAt(0)).getChildAt(0)).bitmapData.dispose();
				_holder.removeChildAt(0);
			}
			trace(_holder.numChildren);
			enable();
			startToPanImage();
		}
		
		//this fucntion is adding an enterFrame event to the panImage function and start's the panning process
		function startToPanImage():void {
			addEventListener(Event.ENTER_FRAME,panImage);
		}
		
		//this fucntion is removing an enterFrame event to the panImage function and stop's the panning process
		function stopToPanImage():void {
			removeEventListener(Event.ENTER_FRAME,panImage);
		}

		//this function has the logic to pann the image
		function panImage(e:Event):void {
			_curImage.x +=  (((stage.stageWidth - _curImage.width))  * (mouseX/(stage.stageWidth))  - (_curImage.x))/5
			_curImage.y +=  (((stage.stageHeight - _curImage.height))  * (mouseY/(stage.stageHeight))  - (_curImage.y))/5 ;
		}
		
		//disable the root 
		private function disable():void{
			Sprite(this.root).mouseChildren = false;
		}
		
		//enable the root 
		private function enable():void{
			Sprite(this.root).mouseChildren = true;
		}
	}
}